package  grib2grd;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import test.LittleEndianDataInputStream;

/**
 * 
 */

/**
 * @author Liu Xinsheng
 * @version 2011-10-25 Tue
 * @function Transform *.grb2 to *.grd, and return array of values
 */
public class Grb2Grd implements HandleGrb2 {

	/* (non-Javadoc)
	 * @see HandleGrb2#GetElement(int, int, int, int, java.lang.String)
	 */
	int m_nYear;
	int m_nMonth;
	int m_nDay;
	int m_nHour;
	String m_strGrbSource;
	String m_strFilter;
	ArrayList<String> m_varList;    // grd列表
	ArrayList<String> m_grib2List;  // 数据列表
	ArrayList<String> m_tempList;
	Map<String,String> m_mapIndex;  // 变量位置索引
	ArrayList<Float>   m_floatData; // 数据值
	
	/**
	 * @param strSource *.grb2所在数据的路径
	 * @param xmlConfig xml配置文件绝对路径
	 */
	public Grb2Grd(String strSource, String xmlConfig){
		m_strGrbSource = strSource;
		m_strFilter = "";
		m_varList = new ArrayList<String>();
		m_grib2List = new ArrayList<String>();
		m_tempList = new ArrayList<String>();
		m_floatData = new ArrayList<Float>();
		m_mapIndex = new HashMap<String, String>();
		m_mapIndex = new Xmlloader(xmlConfig).getXmlMap();
		
	}
	
	public int GetSize() {
		return m_varList.size();

	}
	

	public ArrayList<Float> GetElement(int year, int month, int day, int hour,
			int indexofFile,String strVar) {
		// TODO Auto-generated method stub
		m_nYear = year;
		m_nMonth = month;
		m_nDay = day;
		m_nHour = hour;
		m_strGrbSource = m_strGrbSource + String.format("%d/", year);
		m_strFilter = String.format("%d%02d%02d%02d", m_nYear,
				m_nMonth,m_nDay,m_nHour);
		
		//****************************************************************
		// 1. 获取某时次下 *.grb2 的所有数据
		//****************************************************************
		String strCMD = "ls " + m_strGrbSource + " | grep " + m_strFilter;
		String strDir = "";
		int res = -1;
        try{
			res = executeExe(strCMD); 
        }catch (InterruptedException e){
        	e.printStackTrace();
        }
        if(m_tempList.isEmpty()){
        	return null;
        }
        strDir = m_tempList.get(1);
        
        strCMD = "ls " + m_strGrbSource + strDir + "/*.grb2";
        res = -1;
        try{
			res = executeExe(strCMD);
        }catch (InterruptedException e){
        	e.printStackTrace();
        }
        if(m_tempList.isEmpty()){
        	return null;
        }
        //m_grib2List = m_tempList;
        //for(String t:m_tempList){
        m_grib2List.addAll(m_tempList);
        //}
       
		//****************************************************************
		// 2. 删除路径下已存在的所有grd数据
		//****************************************************************
        strCMD = "rm " + m_strGrbSource + strDir + "/*.grd";
        res = -1;
        try{
			res = executeExe(strCMD);
        }catch (InterruptedException e){
        	e.printStackTrace();
        }

        
		//****************************************************************
		// 3. 生成grd数据的文件名
		//****************************************************************
        for (String t : m_grib2List) {
			m_varList.add(t + "." + strVar + ".grd");
		}
        
		//****************************************************************
		// 4. 执行wgrib2命令 转换数据为二进制grd
		//****************************************************************

		int count = m_varList.size();
		String[] strLev = null;
		
        //for(int i = 0; i < count; i++){
        strLev = m_mapIndex.get(strVar).split("[ ]+");
		//System.out.println(m_varList.get(indexofFile));
		for (int j = 0; j < strLev.length; j++) {

			strCMD = "C:/OpenGrADS/Contents/Cygwin/Versions/2.0.a9.oga.1/i686/wgrib2.exe"
					+ " -d "
					+ strLev[j]
					+ " "
					+ m_grib2List.get(indexofFile)
					+ " -no_header -append -bin " + m_varList.get(indexofFile);

			res = -1;
			try {
				res = executeExe(strCMD);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			if (res != 0) {
				return null;
			}
		}
        // }
        
		// ****************************************************************
		// 5. wgrib2执行成功，读取grd数据返回数值列表
		//*****************************************************************
		
        m_floatData.clear();
        //for(int n = 0; n < count; n++){
        
           try {
        	   LittleEndianDataInputStream pInGrd = new LittleEndianDataInputStream(
					new BufferedInputStream(new FileInputStream(m_varList
							.get(indexofFile))));

			for (int k = 0; k < strLev.length; k++) {
				for (int j = 0; j < 641; j++) {
					for (int i = 0; i < 1280; i++) {

						m_floatData.add(pInGrd.readFloat());
					}
				}
			}

			pInGrd.close();
		} catch (Exception e) {
			e.printStackTrace();
		}	
        	
        // }
        
		return (m_floatData.isEmpty()? null:m_floatData);
		
	}
	
	
	// 执行系统命令
	private int executeExe(String exeName) throws InterruptedException{
		Runtime runTime = Runtime.getRuntime();
		int res = 0;
		BufferedReader in = null;
		m_tempList.clear();
		try {
			Process process = runTime.exec(exeName);
			String str = "";
			in = new BufferedReader(new InputStreamReader(process
					.getInputStream()));
			while ((str = in.readLine()) != null) {
				m_tempList.add(str);
				// System.out.println(str);
			}
			in.close();
			res = process.waitFor();
			System.out.println("命令行 的返回值是：" + res);
			process.destroy();
		} catch (IOException e) {
			System.out.println("调用 命令行 出错！！！");
			e.printStackTrace();
		} finally {
			try {
				if (null != in) {
					in.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return res;
	}
	
    public static void main(String[] Argu){
    	// Usage:
    	// 数据实际存放路径："D:/Sinsonglew/grib2/2011/T639GSI2GRIB2_ORIG_2011010112/",但只需给"D:/Sinsonglew/grib2/"
    	
    	Grb2Grd testG = new Grb2Grd("E:/数据预处理/wgrib2数据示例/","./src/grib2grd/grb2grd.xml");
    	List<Float> t = testG.GetElement(2011, 1, 1, 12, 2, "vwnd");
    	
    	if(t != null){
	    	System.out.println(t.get(0));
	    	System.out.println(t.get(1));
    	}
    }
}
